package com.bing.common.component;

import cn.hutool.json.JSONUtil;
import com.bing.common.model.DataProperty;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.convert.support.DefaultConversionService;
import org.springframework.data.util.ReflectionUtils;
import org.springframework.stereotype.Component;

import java.lang.reflect.Field;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;

/**
 * @Description DataPropertyComponent
 * @Author Bing
 * @Date 2025/8/5 14:32
 */
@Slf4j
@Component
public class DataPropertyComponent {
    // 监控前缀
    @Value("${properties.dataproperty.prefix}")
    private List<String> prefixList;
    // 监控字段
    private final List<DataProperty> dataPropertyList = new CopyOnWriteArrayList<>();

    private final ObjectMapper objectMapper = new ObjectMapper();

    public void addAndSetFieldValue(DataProperty dataProperty,Object value){
        dataPropertyList.add(dataProperty);
        setFieldValue(dataProperty.getBean(), dataProperty.getField(), value);
    }

    /**
     * 刷新字段值
     * @param key
     * @param value
     */
    public void refresh(String key, Object value){
        log.info("====== refresh key ====== : {}", key);
        dataPropertyList.stream().filter(dataProperty -> dataProperty.getKey().equals(key)).forEach(dataProperty -> {
            setFieldValue(dataProperty.getBean(), dataProperty.getField(), value);
        });
    }

    /**
     * 判断是否监控
     * @param key
     * @return
     */
    public boolean isMonitor(final String key){
        return prefixList.stream().filter(prefix -> key.startsWith(prefix)).findFirst().isPresent();
    }

    /**
     * 设置字段值
     */
    private void setFieldValue(Object bean, Field field, Object value) {
        try {
            // 类型转换
            Object convertedValue = convertValue(value, field);
            field.setAccessible(true);
            ReflectionUtils.setField(field, bean, convertedValue);
        } catch (Exception e) {
            log.error("Failed to set field ",e);
        }
    }

    /**
     * 类型转换 - 使用 Jackson 处理泛型
     */
    private Object convertValue(Object value, Field field) {
        Class<?> targetType = field.getType();

        // 如果类型已经匹配，直接返回
        if (targetType.isInstance(value)) {
            return value;
        }

        try {
            String valueStr = value.toString();
            // 检查是否为JSON格式
            if (JSONUtil.isTypeJSON(valueStr)) {
                // 使用 Jackson 处理泛型类型
                return objectMapper.readValue(valueStr, objectMapper.constructType(field.getGenericType()));
            } else {
                // 使用Spring的类型转换服务
                return DefaultConversionService.getSharedInstance().convert(value, targetType);
            }
        } catch (Exception e) {
            log.warn("Conversion failed: " ,e);
            return value;
        }
    }
}